// praxis/services/actuator_manager.cc
#include "praxis/services/actuator_manager.h"

#include <unordered_map>

#include "praxis/hardware/simulated_actuator.h"

namespace praxis {
struct CActuatorManager::Impl {
  std::unordered_map<std::string, std::shared_ptr<IActuator>> actuators;

  void CreateFromConfig(const nlohmann::json& config);
};

void CActuatorManager::Impl::CreateFromConfig(const nlohmann::json& config) {
  if (!config.is_array()) return;
  for (const auto& act_config : config) {
    auto actuator = std::make_shared<CSimulatedActuator>(
        act_config.value("name", ""), act_config.value("unit", ""),
        act_config.value("initial_value", 0.0),
        act_config.value("change_rate_per_second", 10.0));
    actuators[actuator->GetName()] = actuator;
  }
}

CActuatorManager::CActuatorManager(const nlohmann::json& config)
    : impl_(std::make_unique<Impl>()) {
  impl_->CreateFromConfig(config);
}

CActuatorManager::~CActuatorManager() = default;

std::shared_ptr<IActuator> CActuatorManager::GetActuator(
    const std::string& name) {
  auto it = impl_->actuators.find(name);
  return (it != impl_->actuators.end()) ? it->second : nullptr;
}

void CActuatorManager::UpdateAllActuators() {
  for (auto const& [name, actuator] : impl_->actuators) {
    actuator->Update();
  }
}
}  // namespace praxis